﻿using Abp.Application.Services.Dto;
using Abp.Authorization.Users;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.Organizations;
using Camc.Quality.Authorization.Roles;
using Camc.Quality.Authorization.Users;
using Camc.Quality.Bop;
using Camc.Quality.Bop.TreeObject;
using Camc.Quality.Common;
using Camc.Quality.Inspection.InspectionManage;
using Camc.Quality.Inspection.InspectionStrat;
using Camc.Quality.IOperationHistory;
using Camc.Quality.Quality;
using Camc.Quality.QualityAnalysis.RTechniqueEntity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Camc.Quality.Inspection
{
    public class InspectionCheckAppService : QualityAppServiceBase
    {
        public List<TreeClass> treeNodes = new List<TreeClass>();
        private readonly IRepository<InspectionSeverityDesc, Guid> _inspectionSeverityDescRepository;
        private readonly IRepository<InspectionTypeDesc, Guid> _inspectionTypeDescRepository;
        private readonly IRepository<InspectionItemInfo, Guid> _inspectionItemInfoRepository;
        private readonly IRepository<OrganizationUnit, long> _organizationUnitRepository;
        private readonly IRepository<InspectionStandardDesc, Guid> _inspectionStandardDescRepository;
        private readonly RoleManager _roleManager;
        private readonly IRepository<User, long> _userRepository;
        private readonly IRepository<UserRole, long> _userRoleRepository;
        private readonly IOperationHistoryAppService _iOperationHistoryAppService;
        private readonly IRepository<UploadPicture, Guid> _uploadPictureRepository;
        private readonly IRepository<RbopDesc, Guid> _rBopDescRepository;
        private readonly IRepository<RbopNode, Guid> _rBopNodeRepository;
        private readonly IRepository<RTechniqueEntity, Guid> _rtechniqueEntityRepository;
        private readonly IRepository<RProcessesEntity, Guid> _rprocessesEntityRepository;
        private readonly IRepository<RWorkStepEntity, Guid> _rworkStepEntityRepository;
        private readonly IRepository<BopNode, Guid> _bopNodeRepository;

        public InspectionCheckAppService(IRepository<InspectionSeverityDesc, Guid> inspectionSeverityDescRepository,
                             IRepository<InspectionTypeDesc, Guid> inspectionTypeDescRepository,
                             IRepository<InspectionItemInfo, Guid> inspectionItemInfoRepository,
                             IRepository<OrganizationUnit, long> organizationUnitRepository,
                             RoleManager roleManager,
                             IRepository<InspectionStandardDesc, Guid> inspectionStandardDescRepository,
                             IRepository<User, long> userRepository,
                             IRepository<UserRole, long> UserRoleRepository,
                             IOperationHistoryAppService iOperationHistoryAppService,
                             IRepository<UploadPicture, Guid> uploadPictureRepository,
                             IRepository<RbopDesc, Guid> rbopDescRepository,
                             IRepository<RbopNode, Guid> rbopNodeRepository,
                             IRepository<RTechniqueEntity, Guid> rtechniqueEntityRepository,
                             IRepository<RProcessesEntity, Guid> rprocessesEntityRepository,
                             IRepository<RWorkStepEntity, Guid> rworkStepEntityRepository,
                             IRepository<BopNode, Guid> bopNodeRepository
                                    )
        {
            _inspectionSeverityDescRepository = inspectionSeverityDescRepository;
            _inspectionTypeDescRepository = inspectionTypeDescRepository;
            _inspectionItemInfoRepository = inspectionItemInfoRepository;
            _organizationUnitRepository = organizationUnitRepository;
            _roleManager = roleManager;
            _inspectionStandardDescRepository = inspectionStandardDescRepository;
            _userRepository = userRepository;
            _userRoleRepository = UserRoleRepository;
            _iOperationHistoryAppService = iOperationHistoryAppService;
            _uploadPictureRepository = uploadPictureRepository;
            _rBopDescRepository = rbopDescRepository;
            _rBopNodeRepository = rbopNodeRepository;
            _rtechniqueEntityRepository = rtechniqueEntityRepository;
            _rprocessesEntityRepository = rprocessesEntityRepository;
            _rworkStepEntityRepository = rworkStepEntityRepository;
            _bopNodeRepository = bopNodeRepository;
        }
        /// <summary>
        /// 异常管理页面查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<InspectionReturnCheckDto>> GetInspectionStandardDescList(GetInspectionCheckInput input)
        {
            var techIdList = _rBopNodeRepository.GetAll().Where(d => d.RtechniqueEntityId != null).Select(d => d.TechniqueEntityId);
            if (input.DescId != null)
            {
                techIdList = _rBopNodeRepository.GetAll().Where(d => d.RbopDescId == input.DescId).Where(d => d.RtechniqueEntityId != null).Select(d => d.TechniqueEntityId);
            }
            if (input.NodeId != null)
            {
                var currentNode = _rBopNodeRepository.Get((Guid)input.NodeId);
                techIdList = _rBopNodeRepository.GetAll().Where(d => d.RbopDescId == currentNode.RbopDescId && d.NodeCode.StartsWith(currentNode.NodeCode)).Where(d => d.RtechniqueEntityId != null).Select(d => d.TechniqueEntityId);
            }
            var userTemp = _userRepository.GetAll().ToList();
            var inspectionTypeDesc = _inspectionTypeDescRepository.GetAll();
            var inspectionItemInfo = _inspectionItemInfoRepository.GetAll();
            var inspectionSeverityDesc = _inspectionSeverityDescRepository.GetAll();
            var inspectionStardardDesc = (from inspectionStandardDesc in _inspectionStandardDescRepository.GetAll().Where(s => s.IsReturn == 1)
                                          join rtech in _rtechniqueEntityRepository.GetAll()
                                          on inspectionStandardDesc.FileId equals rtech.TechniqueEntityId.ToString() into isd
                                          from isdd in isd.DefaultIfEmpty()
                                          join rpe in _rprocessesEntityRepository.GetAll()
                                          on inspectionStandardDesc.ProcessId equals rpe.ProcessesEntityId into isp
                                          from ispp in isp.DefaultIfEmpty()
                                          join rwse in _rworkStepEntityRepository.GetAll()
                                          on inspectionStandardDesc.StepId equals rwse.WorkStepEntityId into isw
                                          from isww in isw.DefaultIfEmpty()
                                          join tech in techIdList
                                          on inspectionStandardDesc.FileId equals tech.ToString()
                                          select new InspectionReturnCheckDto
                                          {
                                              Id = inspectionStandardDesc.Id,
                                              Code = inspectionStandardDesc.Code,
                                              InspectionTypeDescId = inspectionStandardDesc.InspectionTypeDescId,
                                              InspectionItemInfoId = inspectionStandardDesc.InspectionItemInfoId,
                                              InspectionDetails = inspectionStandardDesc.InspectionDetails,
                                              InspectionSeverityDescId = inspectionStandardDesc.InspectionSeverityDescId,
                                              State = (int)inspectionStandardDesc.State,
                                              CreatorUserId = inspectionStandardDesc.CreatorUserId,
                                              CreationTime = inspectionStandardDesc.CreationTime,
                                              HandlerId = inspectionStandardDesc.HandlerId,
                                              CompleteTime = inspectionStandardDesc.CompleteTime,
                                              CauseAnalysis = inspectionStandardDesc.CauseAnalysis,
                                              TreatmentMeasures = inspectionStandardDesc.TreatmentMeasures,
                                              CostTime = inspectionStandardDesc.CostTime,
                                              ConfirmerId = inspectionStandardDesc.ConfirmerId,
                                              ConfirmTime = inspectionStandardDesc.ConfirmTime,
                                              ConfirmSuggest = inspectionStandardDesc.ConfirmSuggest,
                                              FileId = isdd.Id.ToString() == "" ? null : isdd.Id.ToString(),
                                              ProcessId = ispp == null ? Guid.Empty : ispp.Id,
                                              StepId = isww == null ? Guid.Empty : isww.Id,
                                              TechniqueNumber = inspectionStandardDesc.TechniqueNumber,
                                              TechniqueName = inspectionStandardDesc.TechniqueName,
                                              ProcessesCode = inspectionStandardDesc.ProcessesCode,
                                              ProcessesName = inspectionStandardDesc.ProcessesName,
                                              WorkStepCode = inspectionStandardDesc.WorkStepCode
                                          }).WhereIf(input.ProcessId != null, s => s.ProcessId == input.ProcessId || s.StepId == input.ProcessId).ToList();
                                         /*.WhereIf(input.StepId != null, s => s.StepId == input.StepId).ToList()*/

            var count = inspectionStardardDesc.Count();
            //inspectionStardardDesc = inspectionStardardDesc.OrderByDescending(e => e.CreationTime).PageBy(input);
            //var result = ObjectMapper.Map<List<InspectionStandardDescOutDto>>(inspectionStardardDesc);
            foreach (var item in inspectionStardardDesc)
            {
                if (item.InspectionTypeDescId != Guid.Empty) item.InspectionTypeDesc = inspectionTypeDesc.FirstOrDefault(s => s.Id == item.InspectionTypeDescId).TypeName;
                if (item.InspectionItemInfoId != Guid.Empty) item.InspectionItemInfo = inspectionItemInfo.FirstOrDefault(s => s.Id == item.InspectionItemInfoId).ItemName;
                if (item.InspectionSeverityDescId != Guid.Empty) item.InspectionSeverityDesc = inspectionSeverityDesc.FirstOrDefault(s => s.Id == item.InspectionSeverityDescId).SeverityName;
                if (item.CreatorUserId != null) 
                {
                    var user = userTemp.FirstOrDefault(s => s.Id == item.CreatorUserId);
                    if (user != null) item.Submitter = user.Surname + user.Name;
                }
                if (item.HandlerId != null)
                {
                    var user = userTemp.FirstOrDefault(s => s.Id == item.HandlerId);
                    if (user != null) item.Handler = user.Surname + user.Name;
                }
                if (item.ConfirmerId != null)
                {
                    var user = userTemp.FirstOrDefault(s => s.Id == item.ConfirmerId);
                    if (user != null) item.Confirmer = user.Surname + user.Name;
                }
                //查询上传图片信息
                string url = ConfigHelper.GetAppSetting("App", "GetAppUrl") + "/Inspection/";
                var flieList = _uploadPictureRepository.GetAll().Where(s => s.BusinessId == item.Id);
                flieList = (from up in _uploadPictureRepository.GetAll().Where(s => s.BusinessId == item.Id)
                            select new UploadPicture
                            {
                                Id = up.Id,
                                CreationTime = up.CreationTime,
                                CreatorUserId = up.CreatorUserId,
                                FileName = up.FileName,
                                FileUrl = url + up.FileName,
                                Size = up.Size
                            });
                if (flieList != null)
                {
                    var flieResult = ObjectMapper.Map<List<InspectionFileUploadDto>>(flieList.ToList());
                    item.InspectionFileUploadDto = flieResult.ToList();
                }
            }
            return new PagedResultDto<InspectionReturnCheckDto>(count, inspectionStardardDesc.ToList());
        }
        /// <summary>
        /// 异常数量统计接口
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<InspectionCheckDto> GetInepectionCheckTitle(GetInspectionCheckInput input)
        {
            var techIdList = _rBopNodeRepository.GetAll().Where(d => d.RtechniqueEntityId != null).Select(d => d.TechniqueEntityId);
            if (input.DescId != null)
            {
                techIdList = _rBopNodeRepository.GetAll().Where(d => d.RbopDescId == input.DescId).Where(d => d.RtechniqueEntityId != null).Select(d => d.TechniqueEntityId);
            }
            if (input.NodeId != null)
            {
                var currentNode = _rBopNodeRepository.Get((Guid)input.NodeId);
                techIdList = _rBopNodeRepository.GetAll().Where(d => d.RbopDescId == currentNode.RbopDescId && d.NodeCode.StartsWith(currentNode.NodeCode)).Where(d => d.RtechniqueEntityId != null).Select(d => d.TechniqueEntityId);
            }
            var userTemp = _userRepository.GetAll().ToList();
            var inspectionTypeDesc = _inspectionTypeDescRepository.GetAll();
            var inspectionItemInfo = _inspectionItemInfoRepository.GetAll();
            var inspectionSeverityDesc = _inspectionSeverityDescRepository.GetAll();
            var inspectionStardardDesc = (from inspectionStandardDesc in _inspectionStandardDescRepository.GetAll().Where(s => s.IsReturn == 1)
                                          join rtech in _rtechniqueEntityRepository.GetAll()
                                          on inspectionStandardDesc.FileId equals rtech.TechniqueEntityId.ToString() into isd
                                          from isdd in isd.DefaultIfEmpty()
                                          join rpe in _rprocessesEntityRepository.GetAll()
                                          on inspectionStandardDesc.ProcessId equals rpe.ProcessesEntityId into isp
                                          from ispp in isp.DefaultIfEmpty()
                                          join rwse in _rworkStepEntityRepository.GetAll()
                                              on inspectionStandardDesc.StepId equals rwse.WorkStepEntityId into isw
                                          from isww in isw.DefaultIfEmpty()
                                          join tech in techIdList
                                          on inspectionStandardDesc.FileId equals tech.ToString()
                                          select new InspectionReturnCheckDto
                                          {
                                              Id = inspectionStandardDesc.Id,
                                              Code = inspectionStandardDesc.Code,
                                              InspectionTypeDescId = inspectionStandardDesc.InspectionTypeDescId,
                                              InspectionItemInfoId = inspectionStandardDesc.InspectionItemInfoId,
                                              InspectionDetails = inspectionStandardDesc.InspectionDetails,
                                              InspectionSeverityDescId = inspectionStandardDesc.InspectionSeverityDescId,
                                              State = (int)inspectionStandardDesc.State,
                                              CreatorUserId = inspectionStandardDesc.CreatorUserId,
                                              CreationTime = inspectionStandardDesc.CreationTime,
                                              HandlerId = inspectionStandardDesc.HandlerId,
                                              CompleteTime = inspectionStandardDesc.CompleteTime,
                                              CauseAnalysis = inspectionStandardDesc.CauseAnalysis,
                                              TreatmentMeasures = inspectionStandardDesc.TreatmentMeasures,
                                              CostTime = inspectionStandardDesc.CostTime,
                                              ConfirmerId = inspectionStandardDesc.ConfirmerId,
                                              ConfirmTime = inspectionStandardDesc.ConfirmTime,
                                              ConfirmSuggest = inspectionStandardDesc.ConfirmSuggest,
                                              FileId = isdd.Id.ToString() == "" ? null : isdd.Id.ToString(),
                                              ProcessId = ispp == null ? Guid.Empty : ispp.Id,
                                              StepId = isww == null ? Guid.Empty : isww.Id,
                                              TechniqueNumber = inspectionStandardDesc.TechniqueNumber,
                                              TechniqueName = inspectionStandardDesc.TechniqueName,
                                              ProcessesCode = inspectionStandardDesc.ProcessesCode,
                                              ProcessesName = inspectionStandardDesc.ProcessesName,
                                              WorkStepCode = inspectionStandardDesc.WorkStepCode
                                          }).WhereIf(input.ProcessId != null, s => s.ProcessId == input.ProcessId || s.StepId == input.ProcessId).ToList();
            /*.WhereIf(input.StepId != null, s => s.StepId == input.StepId).ToList()*/
            if (inspectionStardardDesc.Count() != 0)
            {
                int totalCount = inspectionStardardDesc.Count();
                int notCompleteCount = inspectionStardardDesc.Where(s => s.State != 3).Count();
                InspectionCheckDto inspectionCheckDto = new InspectionCheckDto();
                if (totalCount == 0) inspectionCheckDto.ClosePercent = 0;
                else inspectionCheckDto.ClosePercent = (totalCount - notCompleteCount) * 100 / totalCount;//异常关闭率
                inspectionCheckDto.TotalCount = totalCount;//异常总数量
                inspectionCheckDto.NotCompleteCount = notCompleteCount;//未关闭数量

                return inspectionCheckDto;
            }
            else
            {
                return null;
            }
        }
        ///// <summary>
        ///// 未关闭异常分布
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //public List<InspectionNotCompleteDistributionDto> GetNotCompleteDistribution(GetInspectionCheckInput input)
        //{
        //    var inspectionStardardDesc = _inspectionStandardDescRepository.GetAll().Where(s => s.State != States.已完成);
        //    if (input.StartDateTime != null)
        //    {
        //        inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime.AddDays(1) > input.StartDateTime && s.CreationTime.AddDays(-1) < input.EndDateTime);
        //    }
        //    else
        //    {
        //        inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime > DateTime.Now.AddDays(-30));
        //    }
        //    //var inspectionStardardDesc = _inspectionStandardDescRepository.GetAll().Where(s => s.CreationTime > input.StartDateTime.AddDays(-1) && s.CreationTime < input.EndDateTime.AddDays(1) && s.State != States.已完成);

        //    var departmentList = _organizationUnitRepository.GetAll();
        //    List<InspectionNotCompleteDistributionDto> inspectionNotCompleteDistributionDtos = new List<InspectionNotCompleteDistributionDto>();
        //    foreach (var item in departmentList)
        //    {
        //        var inspectionNotCompleteDistributionDto = new InspectionNotCompleteDistributionDto();
        //        int count = (from isd in inspectionStardardDesc
        //                     join it in _inspectionItemInfoRepository.GetAll()
        //                     on isd.InspectionItemInfoId equals it.Id
        //                     where it.OrganizationUnitsId == item.Id
        //                     select isd).Count();
        //        if (count != 0)
        //        {
        //            inspectionNotCompleteDistributionDto.Department = item.DisplayName;
        //            inspectionNotCompleteDistributionDto.Quantity = count;
        //            inspectionNotCompleteDistributionDtos.Add(inspectionNotCompleteDistributionDto);
        //        }
        //    }
        //    return inspectionNotCompleteDistributionDtos;
        //}
    }
}
